/*
 * Copyright (C) 2010 mAPPn.Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mol.market.common.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.text.TextUtils;

import com.mol.market.Constants;
import com.mol.market.R;
import com.mol.market.Session;
import com.mol.market.common.network.ApiAsyncTask.ApiRequestListener;
import com.mol.market.common.network.MarketAPI;
import com.mol.market.common.util.AlarmManageUtils.PushRules;
import com.mol.market.common.util.BooleanLogicUtil.CallBack;
import com.mol.market.common.util.DBUtils.DbOperationResultListener;
import com.mol.market.ui.InstallNecessaryActivity;
import com.mol.market.ui.WebViewActivity;
import com.mol.market.ui_v4.ProductDetailActivity;

/**
 * 通知栏精品软件推荐
 * 
 * @author wufenglong
 * @date 2011-10-14
 * @since Version 0.8.0
 * */
public class AppPushService extends Service implements ApiRequestListener {
    private Session mSession;
    
    @Override
    public void onCreate() {
        mSession = Session.get(getApplicationContext());
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        
        if (intent == null) {
            return super.onStartCommand(intent, flags, startId);
        }
        int type = intent.getIntExtra(Constants.EXTRA_CATEGORY, AlarmManageUtils.CODE_CHECK_UPDATE);
        if (type == AlarmManageUtils.CODE_CHECK_UPDATE) {
            // 检查定期更新提醒
            if (!Utils.isMobileNetwork(getApplicationContext())) {
                // WIFI情况下提醒
                MarketAPI.checkUpgrade(getApplicationContext(), this);
            }
        } else if (type == AlarmManageUtils.CODE_PUSH) {
            
            // 检查推送应用提醒
            MarketAPI.getNotificationRecommend(getApplicationContext(), this);
            
        } else if (type == AlarmManageUtils.CODE_ALARM) {
            
            // 检查推送消息
            MarketAPI.getPushMessage(getApplicationContext(), this);
            
            // 弹出推送消息
            checkNotification();
            AlarmManageUtils.notifyPushService(getApplicationContext(), true);
        } else if (type == PushRules.NOLOGIN_NEW_USER_3_DAY.getEventId()){
            
            NotificationUtils.createCommonWrapNotification(
                    getApplicationContext(), 
                    getString(R.string.app_name),  
                    InstallNecessaryActivity.class, 
                    getString(R.string.app_name), 
                    getString(R.string.push_msg));
            
        } else if (type == PushRules.NOLOGIN_SILENCE_USER_7_DAY.getEventId()){
            
        }
        return Service.START_FLAG_REDELIVERY;
    }

    @SuppressWarnings("unchecked")
    @Override
    public void onSuccess(int method, Object obj) {

        if (method == MarketAPI.ACTION_GET_RECOMMEND_NOTIFICATION) {
            
            AlarmManageUtils.notifyAlarmService(getApplicationContext(), false);
            
        } else if (method == MarketAPI.ACTION_GET_MESSAGE) {
            
            showPushNotification((ArrayList<Notification>) obj);
            
        } else if (method == MarketAPI.ACTION_CHECK_UPGRADE 
                && mSession.getUpgradeNumber() > 0) {
            
            NotificationManager notificationManager = 
                (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            Notification notification = new Notification();
            notification.defaults = Notification.DEFAULT_SOUND;
            notification.icon = R.drawable.notification_icon;
            notification.tickerText = getString(R.string.notification_update_info,
                    mSession.getUpgradeNumber());
            notification.when = System.currentTimeMillis();
            Intent intent = new Intent(Constants.BROADCAST_CLICK_INTENT);
            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0,
                    intent, 0);
            notification.setLatestEventInfo(getApplicationContext(),
                    getString(R.string.notification_update_info_title),
                    getString(R.string.notification_update_info, mSession.getUpgradeNumber()),
                    pendingIntent);
            notification.flags |= Notification.FLAG_AUTO_CANCEL;
            notificationManager.notify(R.drawable.notification_icon, notification);
            
        } 
        stopSelf();
    }
    
    /* 通知栏消息提醒 */
    private void showPushNotification(ArrayList<Notification> notifications) {

        if (!Session.get(getApplicationContext()).isNotificationRecommendApps()) {
            return;
        }

        NotificationManager notificationManager = 
            (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        int i = 0;
        for (Notification notification : notifications) {
            notificationManager.notify(String.valueOf(i++), R.drawable.app_icon, notification);
        }
    }
    
    /**
     * 应用是否已安装的检查工具
     * 
     * @author debug
     * 
     */
    static class PackageItemChecker implements CallBack<String, Boolean> {
        private Set<String> packageSet;

        public PackageItemChecker(Collection<String> packageCollection) {
            packageSet = new HashSet<String>(packageCollection);
        }

        public Boolean run(String x) {
            return packageSet.contains(x);
        }
    }
    
    /**
     * 符合推荐规则的产品
     */
    private static boolean isMatchRule(Context context, Session session, String nid, String rule) {
        
        HashSet<String> packages = session.getInstalledApps();
        
        // 某个应用是否已安装的检查工具
        final PackageItemChecker CHECKER = new PackageItemChecker(packages);

        DBUtils.markItemChecked(context, nid);
        try {
            // 创建规则解释器并判断安装列表是否符合推荐条件
            return new BooleanLogicUtil(rule).excute(CHECKER);
        } catch (Exception e) {
            Utils.E("parse push rule exception", e);
        }
        return false;
    }

    @Override
    public void onError(int method, int statusCode) {

        Utils.D("push service met error [" + statusCode + "]");
        
        stopSelf();
    }
    
    /**
     * 检查是否有应用推送通知
     */
    private void checkNotification() {
        DBUtils.queryPushItems(getApplicationContext(),
                new DbOperationResultListener<ArrayList<HashMap<String, Object>>>() {

                    @Override
                    protected void onQueryResult(ArrayList<HashMap<String, Object>> result) {

                        for (HashMap<String, Object> item : result) {

                            String pid = (String) item.get(Constants.KEY_ID);
                            final String nid = (String) item
                                    .get(Constants.KEY_NOTIFICATION_RECOMMEND_NID);
                            String title = (String) item
                                    .get(Constants.KEY_NOTIFICATION_RECOMMEND_TITLE);
                            String description = (String) item.get(Constants.KEY_DESCRIPTION);
                            String rule = (String) item
                                    .get(Constants.KEY_NOTIFICATION_RECOMMEND_RULE);
                            String url = (String) item.get(Constants.KEY_NOTIFICATION_URL);

                            if (TextUtils.isEmpty(rule)) {
                                // 没有规则的推送
                                showRecommendAppsNotification(title, description, pid, null,
                                        null, url);
                                break;
                            }
                            
                            // 有规则的推送
                            if (isMatchRule(getApplicationContext(), mSession, nid, rule)) {
                              MarketAPI.reportIftttResult(getApplicationContext(), pid, nid,
                                  rule, Constants.REPORT_TYPE_NOTIFICATION);
                              // 符合推送规则
                              showRecommendAppsNotification(title, description, pid, nid,
                                  rule, url);
                              break;
                            }
                        }
                    }
                });
    }

    /* 通知栏推荐提醒 */
    private void showRecommendAppsNotification(String name, String description, String pid,
            String nid, String rule, String url) {

        if (!Session.get(getApplicationContext()).isNotificationRecommendApps()) {
            return;
        }

        NotificationManager notificationManager = 
            (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        Notification notification = new Notification();
        notification.icon = R.drawable.notification_icon;
        notification.tickerText = getString(R.string.notification_recommend_info_title, name);
        notification.when = System.currentTimeMillis();
        notification.defaults = Notification.DEFAULT_LIGHTS;

        Intent intent = null;
        if (TextUtils.isEmpty(url)) {
            intent = new Intent(getApplicationContext(), ProductDetailActivity.class);
            intent.putExtra(Constants.EXTRA_PRODUCT_ID, pid);
            intent.putExtra(Constants.EXTRA_APP_PUSH, true);
            intent.putExtra(Constants.EXTRA_APP_NID, nid);
            intent.putExtra(Constants.EXTRA_APP_RULE, rule);
        } else {
            intent = new Intent(getApplicationContext(), WebViewActivity.class);
            intent.putExtra(Constants.EXTRA_PRODUCT_ID, pid);
            intent.putExtra(Constants.EXTRA_APP_PUSH, true);
            intent.putExtra(Constants.EXTRA_APP_NID, nid);
            intent.putExtra(Constants.EXTRA_APP_RULE, rule);
            intent.putExtra(Constants.EXTRA_APP_URL, url);
        }

        PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent,
                Notification.FLAG_AUTO_CANCEL);

        notification.setLatestEventInfo(getApplicationContext(),
                getString(R.string.notification_recommend_info_title, name), description,
                pendingIntent);
        notification.flags |= Notification.FLAG_AUTO_CANCEL;

        notificationManager.notify(R.drawable.app_icon, notification);
    }


    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

}
